package com.xuxueli.applyModules.utils.testzipswager;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.collections4.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;

/**
 */
public class SwaggerUtils {

    public static String REQUEST_SUFFIX = "-requests";
    public static String RESPONSE_SUFFIX = "-responses";
    public static String REF_PREFIX = "#/components/schemas/";

    /**
     * paths -> request application/json
     */
    public static JSONObject getPathsRequestBody(String serviceCode, Integer type) {
        JSONObject request = new JSONObject(),
            contentTypeObj = new JSONObject(),
            schema = new JSONObject(),
            ref = new JSONObject();
        ref.put("$ref", REF_PREFIX + serviceCode + REQUEST_SUFFIX);
        schema.put("schema", ref);
        if ("FormData".equals(type)) {
            contentTypeObj.put("multipart/form-data", schema);
        } else {
            contentTypeObj.put("application/json", schema);
        }
        request.put("content", contentTypeObj);
        return request;
    }

    /**
     * paths -> responses
     */
    public static JSONObject getPathsResponses(String serviceCode) {
        JSONObject responses = new JSONObject(),
            success = new JSONObject(),
            contentTypeObj = new JSONObject(),
            schema = new JSONObject(),
            ref = new JSONObject();
        ref.put("$ref", REF_PREFIX + serviceCode + RESPONSE_SUFFIX);
        schema.put("schema", ref);
        contentTypeObj.put("application/json", schema);
        success.put("description", "返回参数说明");
        success.put("content", contentTypeObj);
        responses.put("200", success);
        return responses;
    }

    /**
     * components -> schemas -> ?
     */
    public static void setRequestComponentsSchemasObj(JSONObject schemas, String serviceCode,
                                                      List<ServiceRequestParamDTO> bodyParams) {
        JSONObject schema = new JSONObject(),
            properties = new JSONObject();
        schema.put("type", "object");
        for (ServiceRequestParamDTO p : bodyParams) {
            properties.put(p.getCode(), getPropertie(p));
        }
        schema.put("properties", properties);
        schemas.put(serviceCode + SwaggerUtils.REQUEST_SUFFIX, schema);
    }

    /**
     * components -> schemas -> ?
     */
    public static void setResponseComponentsSchemasObj(JSONObject schemas, String serviceCode,
                                                       List<ServiceResponseParamDTO> bodyParams) {
        JSONObject schema = new JSONObject(),
            properties = new JSONObject();
        schema.put("type", "object");
        for (ServiceResponseParamDTO p : bodyParams) {
            properties.put(p.getCode(), getPropertie(p));
        }
        schema.put("properties", properties);
        schemas.put(serviceCode + SwaggerUtils.RESPONSE_SUFFIX, schema);
    }

    private static SwaggerPropertieDTO getPropertie(ServiceRequestParamDTO paramDTO) {
        SwaggerPropertieDTO propertieDTO = new SwaggerPropertieDTO();
        propertieDTO.setType(SwaggerFieldTypeEnum.getById(paramDTO.getFieldTypeId()).getCode());
        propertieDTO.setDescription(paramDTO.getName());
        JSONObject child = null;
        if (CollectionUtils.isNotEmpty(paramDTO.getChildren())) {
            child = new JSONObject();
            for (ServiceRequestParamDTO p : paramDTO.getChildren()) {
                child.put(p.getCode(), getPropertie(p));
            }
        }
        setArray(propertieDTO, child);
        if (SwaggerFieldTypeEnum.FILE.getId().equals(paramDTO.getFieldTypeId())) {
            propertieDTO.setFormat("binary");//文件
        }
        return propertieDTO;
    }

    private static SwaggerPropertieDTO getPropertie(ServiceResponseParamDTO paramDTO) {
        SwaggerPropertieDTO propertieDTO = new SwaggerPropertieDTO();
        propertieDTO.setType(SwaggerFieldTypeEnum.getById(paramDTO.getFieldTypeId()).getCode());
        propertieDTO.setDescription(paramDTO.getName());
        JSONObject child = null;
        if (CollectionUtils.isNotEmpty(paramDTO.getChildren())) {
            child = new JSONObject();
            for (ServiceResponseParamDTO p : paramDTO.getChildren()) {
                child.put(p.getCode(), getPropertie(p));
            }
        }
        setArray(propertieDTO, child);
        return propertieDTO;
    }

    private static void setArray(SwaggerPropertieDTO propertieDTO, JSONObject child) {
        if ("array".equals(propertieDTO.getType())) {
            SwaggerPropertieDTO items = new SwaggerPropertieDTO();
            items.setType("object");
            if (child != null) {
                items.setProperties(child);
            }
            propertieDTO.setItems(items);
        } else {
            propertieDTO.setProperties(child);
        }
    }

    public static void main(String[] args) {
        System.out.println(getPathsResponses("R11C53").toJSONString());
    }

    /**
     * 生成.json格式文件
     */
    public static void exportJsonFile(Object jsonObj, String fileName, HttpServletResponse response) {
        String fullPath = fileName + ".json";
        try {
            File file = new File(fullPath);
            String jsonString = JSON
                .toJSONString(jsonObj, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
                    SerializerFeature.WriteDateUseDateFormat);
            Writer write = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
            write.write(jsonString);
            write.flush();
            write.close();
            FileInputStream fis = new FileInputStream(file);
            //设置响应输出的头类型及下载文件的默认名称
            response.setHeader("Content-Disposition", "attachment;filename="
                .concat(String.valueOf(URLEncoder.encode(fullPath, "UTF-8"))));
            response.setContentType("application/force-download");
            OutputStream os = response.getOutputStream();
            byte[] buf = new byte[1024];
            int len;
            while ((len = fis.read(buf)) != -1) {
                os.write(buf, 0, len);
            }
            fis.close();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
